package routing

import (
	"errors"
	"sync"
)

//RoutingTable 路由表
type RoutingTable struct {
	RoutingName sync.Map
}
type ErgodicAllNode_func func(node *Node)

//NewRoutingTable 。。新建一个路由表
func NewRoutingTable() *RoutingTable {
	return &RoutingTable{
		RoutingName: sync.Map{},
	}
}

//AddrOrUpdateNode 。。在路由表中添加一个节点
func (r *RoutingTable) AddrOrUpdateNode(node *Node) {
	if v, ok := r.RoutingName.Load(node.NodeName); ok {
		v.(*SameNode).AddrOrUpdateNode(node)
	} else {
		samenode := NewSameNode()
		r.RoutingName.Store(node.NodeName, samenode)
		samenode.AddrOrUpdateNode(node)
	}
}

//DeleteNodeByName ..删除所有相同名称的节点
func (r *RoutingTable) DeleteNodeByName(name string) {
	r.RoutingName.Delete(name)
}

//DeleteNode ..删除节点
func (r *RoutingTable) DeleteNode(node *Node) {
	if v, ok := r.RoutingName.Load(node.NodeName); ok {
		v.(*SameNode).DeleteNode(node.Address)
	}
}

//GetRoutTableByName ..获取路由列表
func (r *RoutingTable) GetRoutTableByName(name string) ([]Node, error) {
	if list, ok := r.RoutingName.Load(name); ok {
		return list.([]Node), nil
	}
	return nil, errors.New(name + "`s node is zero")
}

//ErgodicAllNode ..便利所有节点
func (r *RoutingTable) ErgodicAllNode(f ErgodicAllNode_func) {
	r.RoutingName.Range(func(_, value interface{}) bool {
		value.(*SameNode).ErgodicAllNode(f)
		return true
	})
}
